﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using UmlControlLibrary;

namespace UmlControlLibrary
{
    public class UmlModelElementList<T> where T : UmlElement, new()
    {
        public class Events
        {
            public static Event Added = new Event(Event.Added, typeof(UmlModelElementList<T>));
        }

        private ObservableCollection<T> _elements = new ObservableCollection<T>();
        public ObservableCollection<T> Elements
        {
            get { return _elements; }
        }

        private T _current = null;

        /// <summary>
        /// Return the current selected element.
        /// If no element is selected, select the first in the list
        /// If no element is selected, and no element exists, 
        /// create a new element and select it.
        /// </summary>
        public T Current
        {
            get
            {
                if (_current == null)
                {
                    if (Elements.Count > 0)
                        _current = Elements[0];
                    else
                    {
                        _current = new T();
                        Elements.Add(_current);
                    }
                }
                return _current;
            }
            set
            {
                _current = value;
            }
        }

        /// <summary>
        /// get element by it's GUID. Element must exist.
        /// </summary>
        /// <param name="guid">guid of the element to return</param>
        /// <returns>matching element</returns>
        public T GetElementByGuid(string guid)
        {
            var v = Elements.Where(d => d.Guid == guid);
            if (v.Count() == 0)
                return null;
            else
                return v.First();
        }

        public T GetElementByName(string name)
        {
            var v = Elements.Where(d => d.Name == name);
            if (v.Count() == 0)
                return null;
            else
                return v.First();
        }

        public bool AddChildElement(UmlElement element)
        {
            if ((Current.GetElementByGuid(element.Guid) == null)
                && (Current.GetElementByName(element.Name) == null))
            {
                Current.AddElement(element);
//                EventService.BroadcastEvent(this, UmlModelElementList<T>.EventNames.ElementAdded, element);
                return true;
            }
            else
                return false;
        }

        public bool AddElement(T element)
        {
            if (GetElementByGuid(element.Guid) == null)
            {
                if (GetElementByName(element.Name) != null)
                {
                    string name = element.Name;
                    int i = 1;
                    while (GetElementByName(element.Name + "_" + i.ToString()) != null)
                        i++;
                    element.Name += "_" + i.ToString();
                }
                Elements.Add(element);
                EventService.BroadcastEvent(this, UmlModelElementList<T>.Events.Added, element);
                return true;
            }
            else
                return false;
        }
    
    }
}
